/******************************************************************************************************
Copyright (C) 2017 Mestrelab Research S.L. All rights reserved.

This file is part of the MNova scripting toolkit.

Authorized users of MNova Software may use this file freely, but this file is provided AS IS
with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE.
*****************************************************************************************************/

/*globals BaseConverter, NMRSpectrum, File, TextStream, BinaryStream, settings, strings, Env, mainWindow, Dir, Settings, Str*/
/*jslint plusplus: true, indent: 4*/

/** Default constructor of the converter
 * Defines the file filter
*/
function PeakTableConverter() {
	"use strict";
	BaseConverter.call(this);
	this.exportFileFilter = "NMR Peak Table (*.csv *.txt)";
}

PeakTableConverter.prototype = new BaseConverter();

PeakTableConverter.prototype.wantsExport = function (aPageItems) {
	"use strict";
	var i, spec;

	for (i = 0; i < aPageItems.length; i++) {
		if (aPageItems[i].name === "NMR Spectrum") {
			spec = new NMRSpectrum(aPageItems[i]);
			if (spec.isValid() && spec.peaks().count) {
				return true;
			}
		}
	}
	return false;
};

PeakTableConverter.prototype.exportItems = function (aPageItems, aFilename) {
	"use strict";
	var set, strm, i, j, spec, peaks, peak, file, freq, freq1, freq2, hexStr, colSetCount, sz, bstrm, setCount, colTitle, colId, colHidden,
		idMap = [{0: 'ppm', 7: 'hz', 1: 'intens', 2: 'width', 12: 'area', 3: 'type', 11: 'flags', 4: 'maxmin', /*9: 'mult', 13: 'jch',*/ 14: 'kurt', 15: 'imcom', 10: 'annot'},
				{0: 'ppm1', 7: 'hz1', 6: 'ppm2', 8: 'hz2', 1: 'intens', 2: 'width1', 5: 'width2', 12: 'area', 3: 'type', 11: 'flags', 4: 'maxmin', 15: 'imcom', 10: 'annot'}],
		expTempl = ["{ppm}\t{intens}\t{width}\t{area}\t{type}\t{flags}\t{imcom}\t{annot}", "{ppm1}\t{ppm2}\t{intens}\t{width1}\t{width2}\t{area}\t{type}\t{flags}\t{imcom}\t{annot}"];

	try {
		// Create expTempl based on settings
		set = new Settings("NMR Tables");
		hexStr = set.value("Peaks", "");
		if (hexStr) {
			bstrm = new BinaryStream(hexStr);
			sz = bstrm.readInt32();
			bstrm.skip(sz + 4);
			setCount = bstrm.readInt32();
			for (j = 0; j < setCount; j++) {
				expTempl[j] = "";
				sz = bstrm.readInt32();
				bstrm.skip(sz + 4);
				colSetCount = bstrm.readInt32();
				for (i = 0; i < colSetCount; i++) {
					sz = bstrm.readInt32();
					bstrm.skip(sz + 4);
					colTitle = bstrm.readString();
					colHidden = bstrm.readBool();
					bstrm.readInt32(); // decimals
					bstrm.readInt32(); // alignment
					bstrm.readBool(); // is double
					colId = bstrm.readInt32(); // id
					if (!colHidden && idMap[j][colId]) {
						expTempl[j] += "{" + idMap[j][colId] + "}";
						if (i < colSetCount - 1) {
							expTempl[j] += "\t";
						}
					}
				}
			}
		}

		file = new File(aFilename);
		if (file.open(File.WriteOnly)) {
			strm = new TextStream(file);
			strm.precision = settings.value("PeakTableConverter/ExportDecimals", 6);
			for (i = 0; i < aPageItems.length; i++) {
				spec = new NMRSpectrum(aPageItems[i]);
				if (spec.isValid()) {
					strm.writeln(Str.linifyAndQuote(spec.title));
					peaks = spec.peaks();
					if (spec.dimCount === 1) {
						peaks.sort(false);
						freq = spec.frequency();
						for (j = 0; j < peaks.count; j++) {
							peak = peaks.at(j);
							strm.writeln(expTempl[0].formatMap({
								"ppm": peak.delta(),
								"hz": peak.delta() * freq,
								"intens": peak.intensity,
								"width": peak.width() * freq,
								"area": peak.integralInPts(spec),
								"type": peak.typeToString(),
								"flags": peak.flagsToString(),
								"imcom": Str.linifyAndQuote(peak.compoundLabel(spec.solvent)),
								"annot": Str.linifyAndQuote(peak.annotation),
								"kurt": peak.kurtosis,
								"maxmin": peak.kindToString()
							}));
						}
					} else if (spec.dimCount === 2) {
						peaks.sort(false, false);
						freq1 = spec.frequency(1);
						freq2 = spec.frequency(2);
						for (j = 0; j < peaks.count; j++) {
							peak = peaks.at(j);
							strm.writeln(expTempl[1].formatMap({
								"ppm1": peak.delta(1),
								"ppm2": peak.delta(2),
								"hz1": peak.delta(1) * freq1,
								"hz2": peak.delta(2) * freq2,
								"intens": peak.intensity,
								"width1": peak.width(1) * freq1,
								"width2": peak.width(2) * freq2,
								"area": peak.integralInPts(spec),
								"type": peak.typeToString(),
								"flags": peak.flagsToString(),
								"imcom": Str.linifyAndQuote(peak.compoundLabel(spec.solvent)),
								"annot": Str.linifyAndQuote(peak.annotation),
								"maxmin": peak.kindToString()
							}));
						}
					}
					if (peaks.count) {
						strm.writeln();
					}
				}
			}
		}
	} finally {
		file.close();
	}
	return 0;
};

Env.Converters.push(new PeakTableConverter());

PeakTableConverter.PeakTableConverterTest = function () {
	"use strict";
	var retVal = -1,
		peakTableConv = new PeakTableConverter(),
		pageItems = mainWindow.activeDocument.selection();

	if (peakTableConv.wantsExport(pageItems)) {
		retVal = peakTableConv.exportItems(pageItems, Dir.home() + "/PeakTable.txt");
	}
	return retVal;
};
